/*
	Lens by HTML5 UP
	html5up.net | @ajlkn
	Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
*/

var main = (function ($) {
	var _ = {

		/**
		 * Settings.
		 * @var {object}
		 */
		settings: {

			// Preload all images.
			preload: false,

			// Slide duration (must match "duration.slide" in _vars.scss).
			slideDuration: 500,

			// Layout duration (must match "duration.layout" in _vars.scss).
			layoutDuration: 750,

			// Thumbnails per "row" (must match "misc.thumbnails-per-row" in _vars.scss).
			thumbnailsPerRow: 2,

			// Side of main wrapper (must match "misc.main-side" in _vars.scss).
			mainSide: 'right'

		},

		/**
		 * Window.
		 * @var {jQuery}
		 */
		$window: null,

		/**
		 * Body.
		 * @var {jQuery}
		 */
		$body: null,

		/**
		 * Main wrapper.
		 * @var {jQuery}
		 */
		$main: null,

		/**
		 * Thumbnails.
		 * @var {jQuery}
		 */
		$thumbnails: null,

		/**
		 * Viewer.
		 * @var {jQuery}
		 */
		$viewer: null,

		/**
		 * Toggle.
		 * @var {jQuery}
		 */
		$toggle: null,

		/**
		 * Nav (next).
		 * @var {jQuery}
		 */
		$navNext: null,

		/**
		 * Nav (previous).
		 * @var {jQuery}
		 */
		$navPrevious: null,

		/**
		 * Slides.
		 * @var {array}
		 */
		slides: [],

		/**
		 * Current slide index.
		 * @var {integer}
		 */
		current: null,

		/**
		 * Lock state.
		 * @var {bool}
		 */
		locked: false,

		/**
		 * Keyboard shortcuts.
		 * @var {object}
		 */
		keys: {

			// Escape: Toggle main wrapper.
			27: function () {
				_.toggle();
			},

			// Up: Move up.
			38: function () {
				_.up();
			},

			// Down: Move down.
			40: function () {
				_.down();
			},

			// Space: Next.
			32: function () {
				_.next();
			},

			// Right Arrow: Next.
			39: function () {
				_.next();
			},

			// Left Arrow: Previous.
			37: function () {
				_.previous();
			}

		},

		/**
		 * Initialize properties.
		 */
		initProperties: function () {

			// Window, body.
			_.$window = $(window);
			_.$body = $('body');

			// Thumbnails.
			_.$thumbnails = $('#thumbnails');

			// Viewer.
			_.$viewer = $(
				'<div id="viewer">' +
				'<div class="inner">' +
				'<div class="nav-next"></div>' +
				'<div class="nav-previous"></div>' +
				'<div class="toggle"></div>' +
				'</div>' +
				'</div>'
			).appendTo(_.$body);

			// Nav.
			_.$navNext = _.$viewer.find('.nav-next');
			_.$navPrevious = _.$viewer.find('.nav-previous');

			// Main wrapper.
			_.$main = $('#main');

			// Toggle.
			$('<div class="toggle"></div>')
				.appendTo(_.$main);

			_.$toggle = $('.toggle');

			// IE<9: Fix viewer width (no calc support).
			if (skel.vars.IEVersion < 9)
				_.$window
					.on('resize', function () {
						window.setTimeout(function () {
							_.$viewer.css('width', _.$window.width() - _.$main.width());
						}, 100);
					})
					.trigger('resize');

		},

		/**
		 * Initialize events.
		 */
		initEvents: function () {

			// Window.

			// Remove is-loading-* classes on load.
			_.$window.on('load', function () {

				_.$body.removeClass('is-loading-0');

				window.setTimeout(function () {
					_.$body.removeClass('is-loading-1');
				}, 100);

				window.setTimeout(function () {
					_.$body.removeClass('is-loading-2');
				}, 100 + Math.max(_.settings.layoutDuration - 150, 0));

			});

			// Disable animations/transitions on resize.
			var resizeTimeout;

			_.$window.on('resize', function () {

				_.$body.addClass('is-loading-0');
				window.clearTimeout(resizeTimeout);

				resizeTimeout = window.setTimeout(function () {
					_.$body.removeClass('is-loading-0');
				}, 100);

			});

			// Viewer.

			// Hide main wrapper on tap (<= medium only).
			_.$viewer.on('touchend', function () {

				if (skel.breakpoint('medium').active)
					_.hide();

			});

			// Touch gestures.
			_.$viewer
				.on('touchstart', function (event) {

					// Record start position.
					_.$viewer.touchPosX = event.originalEvent.touches[0].pageX;
					_.$viewer.touchPosY = event.originalEvent.touches[0].pageY;

				})
				.on('touchmove', function (event) {

					// No start position recorded? Bail.
					if (_.$viewer.touchPosX === null
						|| _.$viewer.touchPosY === null)
						return;

					// Calculate stuff.
					var diffX = _.$viewer.touchPosX - event.originalEvent.touches[0].pageX,
						diffY = _.$viewer.touchPosY - event.originalEvent.touches[0].pageY;
					boundary = 20,
						delta = 50;

					// Swipe left (next).
					if ((diffY < boundary && diffY > (-1 * boundary)) && (diffX > delta))
						_.next();

					// Swipe right (previous).
					else if ((diffY < boundary && diffY > (-1 * boundary)) && (diffX < (-1 * delta)))
						_.previous();

					// Overscroll fix.
					var th = _.$viewer.outerHeight(),
						ts = (_.$viewer.get(0).scrollHeight - _.$viewer.scrollTop());

					if ((_.$viewer.scrollTop() <= 0 && diffY < 0)
						|| (ts > (th - 2) && ts < (th + 2) && diffY > 0)) {

						event.preventDefault();
						event.stopPropagation();

					}

				});

			// Main.

			// Touch gestures.
			_.$main
				.on('touchstart', function (event) {

					// Bail on xsmall.
					if (skel.breakpoint('xsmall').active)
						return;

					// Record start position.
					_.$main.touchPosX = event.originalEvent.touches[0].pageX;
					_.$main.touchPosY = event.originalEvent.touches[0].pageY;

				})
				.on('touchmove', function (event) {

					// Bail on xsmall.
					if (skel.breakpoint('xsmall').active)
						return;

					// No start position recorded? Bail.
					if (_.$main.touchPosX === null
						|| _.$main.touchPosY === null)
						return;

					// Calculate stuff.
					var diffX = _.$main.touchPosX - event.originalEvent.touches[0].pageX,
						diffY = _.$main.touchPosY - event.originalEvent.touches[0].pageY;
					boundary = 20,
						delta = 50,
						result = false;

					// Swipe to close.
					switch (_.settings.mainSide) {

						case 'left':
							result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX > delta);
							break;

						case 'right':
							result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX < (-1 * delta));
							break;

						default:
							break;

					}

					if (result)
						_.hide();

					// Overscroll fix.
					var th = _.$main.outerHeight(),
						ts = (_.$main.get(0).scrollHeight - _.$main.scrollTop());

					if ((_.$main.scrollTop() <= 0 && diffY < 0)
						|| (ts > (th - 2) && ts < (th + 2) && diffY > 0)) {

						event.preventDefault();
						event.stopPropagation();

					}

				});
			// Toggle.
			_.$toggle.on('click', function () {
				_.toggle();
			});

			// Prevent event from bubbling up to "hide event on tap" event.
			_.$toggle.on('touchend', function (event) {
				event.stopPropagation();
			});

			// Nav.
			_.$navNext.on('click', function () {
				_.next();
			});

			_.$navPrevious.on('click', function () {
				_.previous();
			});

			// Keyboard shortcuts.

			// Ignore shortcuts within form elements.
			_.$body.on('keydown', 'input,select,textarea', function (event) {
				event.stopPropagation();
			});

			_.$window.on('keydown', function (event) {

				// Ignore if xsmall is active.
				if (skel.breakpoint('xsmall').active)
					return;

				// Check keycode.
				if (event.keyCode in _.keys) {

					// Stop other events.
					event.stopPropagation();
					event.preventDefault();

					// Call shortcut.
					(_.keys[event.keyCode])();

				}

			});

		},

		/**
		 * Initialize viewer.
		 */
		initViewer: function () {

			// Bind thumbnail click event.
			_.$thumbnails
				.on('click', '.thumbnail', function (event) {

					var $this = $(this);

					// Stop other events.
					event.preventDefault();
					event.stopPropagation();

					// Locked? Blur.
					if (_.locked)
						$this.blur();

					// Switch to this thumbnail's slide.
					_.switchTo($this.data('index'));

				});

			// Create slides from thumbnails.
			_.$thumbnails.children()
				.each(function () {

					var $this = $(this),
						$thumbnail = $this.children('.thumbnail'),
						s;

					// Slide object.
					s = {
						$parent: $this,
						$slide: null,
						$slideImage: null,
						$slideCaption: null,
						url: $thumbnail.attr('href'),
						loaded: false
					};

					// Parent.
					$this.attr('tabIndex', '-1');

					// Slide.

					// Create elements.
					s.$slide = $('<div class="slide"><div class="caption"></div><div class="image"></div></div>');

					// Image.
					s.$slideImage = s.$slide.children('.image');

					// Set background stuff.
					s.$slideImage
						.css('background-image', '')
						.css('background-position', ($thumbnail.data('position') || 'center'));

					// Caption.
					s.$slideCaption = s.$slide.find('.caption');

					// Move everything *except* the thumbnail itself to the caption.
					$this.children().not($thumbnail)
						.appendTo(s.$slideCaption);

					// Preload?
					if (_.settings.preload) {

						// Force image to download.
						var $img = $('<img src="' + s.url + '" />');

						// Set slide's background image to it.
						s.$slideImage
							.css('background-image', 'url(' + s.url + ')');

						// Mark slide as loaded.
						s.$slide.addClass('loaded');
						s.loaded = true;

					}

					// Add to slides array.
					_.slides.push(s);

					// Set thumbnail's index.
					$thumbnail.data('index', _.slides.length - 1);

				});

		},

		/**
		 * Initialize stuff.
		 */
		init: function () {

			// IE<10: Zero out transition delays.
			if (skel.vars.IEVersion < 10) {

				_.settings.slideDuration = 0;
				_.settings.layoutDuration = 0;

			}

			// Skel.
			skel.breakpoints({
				xlarge: '(max-width: 1680px)',
				large: '(max-width: 1280px)',
				medium: '(max-width: 980px)',
				small: '(max-width: 736px)',
				xsmall: '(max-width: 480px)'
			});

			// Everything else.
			_.initProperties();
			_.initViewer();
			_.initEvents();

			// Initial slide.
			window.setTimeout(function () {

				// Show first slide if xsmall isn't active or it just deactivated.
				skel.on('-xsmall !xsmall', function () {

					if (_.current === null) {
						var firstSlide = 0;
						if (window.location.hash)
							firstSlide = window.location.hash.substring(1);
						_.switchTo(firstSlide, true);
					}

				});

			}, 0);

		},

		/**
		 * Switch to a specific slide.
		 * @param {integer} index Index.
		 */
		switchTo: function (index, noHide) {

			// Already at index and xsmall isn't active? Bail.
			if (_.current == index
				&& !skel.breakpoint('xsmall').active)
				return;

			// Locked? Bail.
			if (_.locked)
				return;

			// Lock.
			_.locked = true;

			// Hide main wrapper if medium is active.
			if (!noHide
				&& skel.breakpoint('medium').active
				&& skel.vars.IEVersion > 8)
				_.hide();

			// Get slides.
			var oldSlide = (_.current !== null ? _.slides[_.current] : null),
				newSlide = _.slides[index];

			// Update current.
			_.current = index;
			window.location.hash = '#' + index;

			// Deactivate old slide (if there is one).
			if (oldSlide) {

				// Thumbnail.
				oldSlide.$parent
					.removeClass('active');

				// Slide.
				oldSlide.$slide.removeClass('active');

			}

			// Activate new slide.

			// Thumbnail.
			newSlide.$parent
				.addClass('active')
				.focus();

			// Slide.
			var f = function () {

				// Old slide exists? Detach it.
				if (oldSlide)
					oldSlide.$slide.detach();

				// Attach new slide.
				newSlide.$slide.appendTo(_.$viewer);

				// New slide not yet loaded?
				if (!newSlide.loaded) {

					window.setTimeout(function () {

						// Mark as loading.
						newSlide.$slide.addClass('loading');

						// Wait for it to load.
						$('<img src="' + newSlide.url + '" />').on('load', function () {
							//window.setTimeout(function() {

							// Set background image.
							newSlide.$slideImage
								.css('background-image', 'url("' + newSlide.url + '")');

							// Mark as loaded.
							newSlide.loaded = true;
							newSlide.$slide.removeClass('loading');

							// Mark as active.
							newSlide.$slide.addClass('active');

							// Unlock.
							window.setTimeout(function () {
								_.locked = false;
							}, 100);

							//}, 1000);
						});

					}, 100);

				}

				// Otherwise ...
				else {

					window.setTimeout(function () {

						// Mark as active.
						newSlide.$slide.addClass('active');

						// Unlock.
						window.setTimeout(function () {
							_.locked = false;
						}, 100);

					}, 100);

				}

			};

			// No old slide? Switch immediately.
			if (!oldSlide)
				(f)();

			// Otherwise, wait for old slide to disappear first.
			else
				window.setTimeout(f, _.settings.slideDuration);

		},

		/**
		 * Switches to the next slide.
		 */
		next: function () {

			// Calculate new index.
			var i, c = _.current, l = _.slides.length;

			if (c >= l - 1)
				i = 0;
			else
				i = c + 1;

			// Switch.
			_.switchTo(i);

		},

		/**
		 * Switches to the previous slide.
		 */
		previous: function () {

			// Calculate new index.
			var i, c = _.current, l = _.slides.length;

			if (c <= 0)
				i = l - 1;
			else
				i = c - 1;

			// Switch.
			_.switchTo(i);

		},

		/**
		 * Switches to slide "above" current.
		 */
		up: function () {

			// Fullscreen? Bail.
			if (_.$body.hasClass('fullscreen'))
				return;

			// Calculate new index.
			var i, c = _.current, l = _.slides.length, tpr = _.settings.thumbnailsPerRow;

			if (c <= (tpr - 1))
				i = l - (tpr - 1 - c) - 1;
			else
				i = c - tpr;

			// Switch.
			_.switchTo(i);

		},

		/**
		 * Switches to slide "below" current.
		 */
		down: function () {

			// Fullscreen? Bail.
			if (_.$body.hasClass('fullscreen'))
				return;

			// Calculate new index.
			var i, c = _.current, l = _.slides.length, tpr = _.settings.thumbnailsPerRow;

			if (c >= l - tpr)
				i = c - l + tpr;
			else
				i = c + tpr;

			// Switch.
			_.switchTo(i);

		},

		/**
		 * Shows the main wrapper.
		 */
		show: function () {

			// Already visible? Bail.
			if (!_.$body.hasClass('fullscreen'))
				return;

			// Show main wrapper.
			_.$body.removeClass('fullscreen');

			// Focus.
			_.$main.focus();

		},

		/**
		 * Hides the main wrapper.
		 */
		hide: function () {

			// Already hidden? Bail.
			if (_.$body.hasClass('fullscreen'))
				return;

			// Hide main wrapper.
			_.$body.addClass('fullscreen');

			// Blur.
			_.$main.blur();

		},

		/**
		 * Toggles main wrapper.
		 */
		toggle: function () {

			if (_.$body.hasClass('fullscreen'))
				_.show();
			else
				_.hide();

		},

	}; return _;
})(jQuery); main.init();
